package cn.itsource.ymcc.mq;

import cn.itsource.ymcc.constant.ErrorConstantCode;
import cn.itsource.ymcc.constant.MQConstants;
import cn.itsource.ymcc.domain.CourseMarket;
import cn.itsource.ymcc.domain.CourseUserLearn;
import cn.itsource.ymcc.dto.NotifyPayMsgDto;
import cn.itsource.ymcc.exception.GlobalException;
import cn.itsource.ymcc.service.ICourseMarketService;
import cn.itsource.ymcc.service.ICourseService;
import cn.itsource.ymcc.service.ICourseUserLearnService;
import cn.itsource.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.Date;

@RocketMQMessageListener(
        consumerGroup = MQConstants.TX_PAY_NOTIFY_COMSUMER_GROUP,
        topic = MQConstants.TX_PAY_NOTIFY_TOPIC,
        selectorExpression = "*",
        messageModel = MessageModel.BROADCASTING //广播，所有的消费者都要能消费回调消息

)
@Service
@Slf4j
public class NotifyPayMessageLinster implements RocketMQListener<MessageExt> {


    @Autowired
    private ICourseUserLearnService courseUserLearnService;

    @Autowired
    private ICourseService courseService;

    @Autowired
    private ICourseMarketService marketService;

    @Override
    public void onMessage(MessageExt messageExt) {

        NotifyPayMsgDto msgDto = null;
        try{
            byte[] body = messageExt.getBody();
            String jsonStr = new String(body, StandardCharsets.UTF_8);
            msgDto = JSON.parseObject(jsonStr, NotifyPayMsgDto.class);

        }catch (Exception e){
            e.printStackTrace();
            throw new GlobalException("消费回调通知异常！");
        }

        AssertUtil.isNotNull(msgDto, ErrorConstantCode.PARAMETER_NOT_BE_NULL);
        log.info("保存用户的课程购买记录：{}",msgDto);


        String orderNo = msgDto.getOrderNo();
        synchronized (orderNo){

            Wrapper<CourseUserLearn> wrapper = new EntityWrapper<>();
            wrapper.eq("course_order_no",orderNo);
            CourseUserLearn learn = courseUserLearnService.selectOne(wrapper);

            Date date = new Date();

            if(learn!=null){
                log.info("订单已经被保存过了：{}",learn);
                return;
            }else {
                log.info("保存新的课程和用户购买记录！");
                // 根据订单编号查询收购买的课程集合
                String courseIds = msgDto.getCourseIds();
                if(courseIds.contains(",")){
                    String[] courseIdsArr = courseIds.split(",");
                    for (int i = 0; i < courseIdsArr.length; i++) {
                        saveUserForCourseID(msgDto, orderNo, date, courseIdsArr[i]);
                    }
                }else{
                    // 单个课程
                    saveUserForCourseID(msgDto, orderNo, date, courseIds);
                }


            }
        }
    }

    /**
     * 保存用户和课程的购买记录
     * @param msgDto
     * @param orderNo
     * @param date
     * @param courseId
     */
    private void saveUserForCourseID(NotifyPayMsgDto msgDto, String orderNo, Date date, String courseId) {
        CourseUserLearn learn;
        CourseMarket market = marketService.selectById(courseId);


        // 用户已经购买过 -- 修改课程有效期
        Wrapper<CourseUserLearn> wrapper = new EntityWrapper<>();
        wrapper.eq("login_id",msgDto.getUserId()).and().eq("course_id",courseId);
        CourseUserLearn courseUserLearn = courseUserLearnService.selectOne(wrapper);

        if(courseUserLearn == null){
            log.info("用户没有购买过：{}",courseUserLearn);
            // 用户没有购买过 -- 新增记录就ok
            learn = new CourseUserLearn();
            learn.setLoginId(msgDto.getUserId());
            learn.setStartTime(date);
            learn.setEndTime(DateUtils.addDays(date,market.getValidDays()));
            learn.setState(0);
            learn.setCourseId(Long.valueOf(courseId));
            learn.setCourseOrderNo(orderNo);
            learn.setCreateTime(date);
            courseUserLearnService.insert(learn);
            log.info("新增用户购买记录：{}",courseUserLearn);
            return;
        }


        // 判断 课程状态：
        if(courseUserLearn.getState().equals(CourseUserLearn.YES_BUY)){
            log.info("已购买，未过期：{}",courseUserLearn);
            // 已购买 -- 在原来的过期时候的基础上，添加课程的有效时长
            date = courseUserLearn.getEndTime();
            courseUserLearn.setEndTime(DateUtils.addDays(date,market.getValidDays()));

        }

        if(courseUserLearn.getState().equals(CourseUserLearn.PAST_DUE)){
            log.info("已购买，过期：{}",courseUserLearn);
            // 过期，在今天的基础上添加 课程的有效时长
            //课程的有效时长
            courseUserLearn.setEndTime(DateUtils.addDays(date,market.getValidDays()));
            courseUserLearn.setState(CourseUserLearn.YES_BUY);

        }


        courseUserLearn.setCourseOrderNo(orderNo);
        courseUserLearn.setCreateTime(date);

        log.info("修改有效时间：{}",courseUserLearn);
        courseUserLearnService.updateById(courseUserLearn);

    }
}
